1 00:00:00,260 --> 00:00:00,950 Hey there. 2 00:00:00,950 --> 00:00:01,850 Welcome back. 3 00:00:01,850 --> 00:00:06,680 In this lecture we're going to be exploring a service called the Run Service. 4 00:00:06,680 --> 00:00:13,940 This is a crucial and fundamental service for being able to access methods and events for time management 5 00:00:13,940 --> 00:00:18,440 of your code, and also checking what the context of your code is executing it. 6 00:00:18,470 --> 00:00:23,930 It has several events that get fired at different points in the creation of a single frame. 7 00:00:23,930 --> 00:00:28,280 So the service allows you to be able to execute code every single frame. 8 00:00:28,280 --> 00:00:32,500 The documentation states that the run service contains methods and events for time management, as well 9 00:00:32,500 --> 00:00:35,590 as for managing the context in which a game or script is running. 10 00:00:35,590 --> 00:00:41,110 Methods like is client, is server is studio can help you determine under what context code is running. 11 00:00:41,110 --> 00:00:45,700 These methods are useful for module scripts that may be required by both client and server scripts. 12 00:00:45,700 --> 00:00:50,560 Furthermore, is studio can be used to add special behaviors for in studio testing. 13 00:00:50,560 --> 00:00:56,820 Run service also houses events that allow your code to adhere to Roblox frame by frame loop, such as 14 00:00:56,820 --> 00:01:00,390 pre animation, pre simulation, heartbeat, and Pre-render. 15 00:01:00,390 --> 00:01:06,240 Selecting the proper event to use for any case is important, so you should read the task scheduler 16 00:01:06,240 --> 00:01:08,850 documentation to make an informed decision. 17 00:01:08,850 --> 00:01:13,830 If we take a look at the documentation about the task scheduler, this is the system that's responsible 18 00:01:13,830 --> 00:01:18,670 for basically scheduling all the tasks and things that need to execute in your game. 19 00:01:18,670 --> 00:01:24,460 And if we scroll down, there's going to be a picture right here that basically shows us how a single 20 00:01:24,460 --> 00:01:26,050 frame is created. 21 00:01:26,050 --> 00:01:30,910 It says the task scheduler categorizes and completes tasks in the following order. 22 00:01:30,910 --> 00:01:35,710 Some tasks may not perform work in a frame, while others may run multiple times. 23 00:01:35,710 --> 00:01:40,000 So the first thing that's going to happen when a new frame is being created is that we're first going 24 00:01:40,000 --> 00:01:41,470 to listen to any user input. 25 00:01:41,470 --> 00:01:42,550 So it says input events. 26 00:01:42,550 --> 00:01:47,440 The user input service and bound functions to the context action service are handled first, such as 27 00:01:47,440 --> 00:01:54,430 key presses, mouse movements, touches, gamepad vibration, etc. then we go into the rendering phase 28 00:01:54,430 --> 00:01:58,330 now before the screen is rendered so things are drawn on the screen. 29 00:01:58,330 --> 00:02:02,950 It's going to fire an event called a render step, and it's also going to go through and execute a bunch 30 00:02:02,950 --> 00:02:05,510 of functions bound to the render step event. 31 00:02:05,510 --> 00:02:10,700 It says all functions bound with the bind to render step method are called in priority order. 32 00:02:10,700 --> 00:02:17,120 In the built in player module, the camera and character control scripts bind callbacks at certain priorities 33 00:02:17,120 --> 00:02:21,980 determined by the render priority enum, and then it's going to fire the render stepped event. 34 00:02:21,980 --> 00:02:26,780 It says it's fired, and as with all events, connected functions are called with the most recently 35 00:02:26,780 --> 00:02:33,750 connected callback ran first and then after the screen is drawn and rendered, it says any further changes 36 00:02:33,750 --> 00:02:35,310 won't render until the next frame. 37 00:02:35,310 --> 00:02:41,520 So if you want to make a change on the screen for rendering, then you might want to do it before the 38 00:02:41,520 --> 00:02:42,240 screen is drawn. 39 00:02:42,240 --> 00:02:46,710 Otherwise, if you do it further down in the frame, you're going to have to wait till the next frame. 40 00:02:46,800 --> 00:02:52,140 Then it says replication receive jobs, incoming property changes and event firings are applied. 41 00:02:52,140 --> 00:02:52,680 Resume. 42 00:02:52,680 --> 00:02:54,500 Wait weight states, Lua garbage collection. 43 00:02:54,500 --> 00:02:58,670 And then we get to the simulation part of the frame where it's going to do physics. 44 00:02:58,670 --> 00:03:04,010 And there's another event in the run service called stepped, which fires before the internal physics 45 00:03:04,010 --> 00:03:04,460 step. 46 00:03:04,460 --> 00:03:07,430 So it says relative positions of parts joined by motor six. 47 00:03:07,430 --> 00:03:10,790 These are updated part contacts and constraints are updated. 48 00:03:10,790 --> 00:03:11,840 Slash solved. 49 00:03:11,840 --> 00:03:16,400 This can happen multiple times per frame since physics will update at 240Hz. 50 00:03:16,400 --> 00:03:21,980 Based, part touched and related physics events fire after all world steps are complete, blah blah 51 00:03:21,980 --> 00:03:22,160 blah. 52 00:03:22,160 --> 00:03:28,070 This is a bunch of information, but basically after the screen is rendered and physics are done, then 53 00:03:28,070 --> 00:03:31,190 the final event is going to be fired, which is the heartbeat event. 54 00:03:31,190 --> 00:03:34,880 Back in the run service documentation, let's actually take a look at all of the events that we have 55 00:03:34,880 --> 00:03:35,450 available. 56 00:03:35,450 --> 00:03:37,610 And you're going to notice that there's actually quite a few. 57 00:03:37,640 --> 00:03:39,290 We have seven events here. 58 00:03:39,290 --> 00:03:39,740 Now. 59 00:03:39,740 --> 00:03:44,690 The most common ones in the original ones are going to be heartbeat, render stepped and stepped. 60 00:03:44,720 --> 00:03:49,550 These are the three events that we saw in that image that I just showed you from the Task Scheduler 61 00:03:49,550 --> 00:03:50,690 documentation page. 62 00:03:50,690 --> 00:03:56,060 Now post simulation, pre animation, Pre-render and pre simulation are all new events. 63 00:03:56,060 --> 00:04:02,480 And these events are likely going to replace heartbeat render step and stepped post simulation as the 64 00:04:02,480 --> 00:04:05,740 name suggests happens after physics are calculated. 65 00:04:05,740 --> 00:04:09,460 So this event is actually just the same as the heartbeat event. 66 00:04:09,460 --> 00:04:14,470 This is just the new name they gave to it, and this event is probably going to be deprecated in the 67 00:04:14,470 --> 00:04:15,250 future. 68 00:04:15,280 --> 00:04:18,310 The next one we're going to have here is called pre animation. 69 00:04:18,310 --> 00:04:26,980 This is actually a new event that executes or fires before the simulation happens in the game, but 70 00:04:26,980 --> 00:04:29,880 it also happens after the screen is rendered. 71 00:04:29,880 --> 00:04:33,210 So there's a stage in which animations are ran. 72 00:04:33,210 --> 00:04:39,120 And this pre animation event, as the name suggests, happens right before animations are calculated. 73 00:04:39,150 --> 00:04:42,840 This next event, called Pre-render is the same as render step. 74 00:04:42,840 --> 00:04:46,470 This fires, you know before the frame is rendered. 75 00:04:46,470 --> 00:04:51,870 And then once it's all done, then it's going to go and render or draw things onto the screen. 76 00:04:51,870 --> 00:04:54,520 So render step and pre render are the same thing. 77 00:04:54,520 --> 00:04:58,810 And then pre simulation and stepped are also the exact same thing. 78 00:04:58,810 --> 00:05:02,170 So the order in which these events execute are as follows. 79 00:05:02,170 --> 00:05:07,000 The first one is going to be render stepped then stepped and then heartbeat. 80 00:05:07,000 --> 00:05:13,390 And then with the new events what's going to fire first is pre render, then it's going to fire pre 81 00:05:13,390 --> 00:05:14,200 animation. 82 00:05:14,200 --> 00:05:16,270 Then it's going to fire pre simulation. 83 00:05:16,270 --> 00:05:19,050 And then finally it will fire post simulation. 84 00:05:19,050 --> 00:05:21,780 And this all happens in a single frame. 85 00:05:21,780 --> 00:05:27,840 Now to prove the order of these events I have this local script here that is connected to every single 86 00:05:27,840 --> 00:05:29,520 event in the run service. 87 00:05:29,520 --> 00:05:36,570 And I'm using the debug library to create some tags within the micro profiler, so we can go ahead and 88 00:05:36,570 --> 00:05:39,540 take a look at them when we open the Micro Profiler. 89 00:05:39,540 --> 00:05:46,290 But as you can see I'm connected to pre render render stepped stepped pre animation, post simulation, 90 00:05:46,290 --> 00:05:48,870 heartbeat and post simulation. 91 00:05:48,870 --> 00:05:50,580 Oops I said post simulation. 92 00:05:50,580 --> 00:05:52,200 This is pre simulation. 93 00:05:52,200 --> 00:05:53,580 This one's post simulation. 94 00:05:53,580 --> 00:05:56,640 Now the code inside of here is not doing anything special. 95 00:05:56,640 --> 00:06:00,090 This is just so we can kind of push out the frame time. 96 00:06:00,090 --> 00:06:03,750 So we can actually see these tags appear in the micro profiler. 97 00:06:03,750 --> 00:06:06,800 So let's go ahead and do a quick play test of the game. 98 00:06:06,800 --> 00:06:10,100 And let me go ahead and open up the micro profiler. 99 00:06:10,460 --> 00:06:13,130 And then I'm going to pause it pressing control and P. 100 00:06:13,130 --> 00:06:16,520 And then I open the micro profiler using control and F6. 101 00:06:16,520 --> 00:06:18,860 That's how you open the micro profiler. 102 00:06:18,860 --> 00:06:20,450 And then I'm going to pause it. 103 00:06:20,450 --> 00:06:23,810 And this might seem a little bit advanced to you at the moment. 104 00:06:23,810 --> 00:06:24,650 That's okay. 105 00:06:24,650 --> 00:06:30,200 You're going to learn about the micro profiler when we start talking or learning about parallel, will 106 00:06:30,200 --> 00:06:30,350 you? 107 00:06:30,350 --> 00:06:35,450 But that comes, I believe, in a later lecture, but I'm just going to select a frame here. 108 00:06:36,230 --> 00:06:41,720 And what I'm going to do is I'm going to verify the order that things are being executed in. 109 00:06:41,720 --> 00:06:43,670 So what is a good example. 110 00:06:43,670 --> 00:06:44,150 Let me see. 111 00:06:44,150 --> 00:06:44,510 Okay. 112 00:06:44,510 --> 00:06:46,490 Let's let's pick this frame right here. 113 00:06:46,490 --> 00:06:50,480 This is one frame because you can see this one light line and the other white line. 114 00:06:50,480 --> 00:06:54,460 This signifies one frame that was rendered. 115 00:06:54,580 --> 00:07:00,400 So the first thing that's going to happen, as you can see down here, there's our render step work 116 00:07:00,400 --> 00:07:01,690 and our pre render work. 117 00:07:01,690 --> 00:07:06,310 So these are the first two events that fire and happen in the beginning of the frame. 118 00:07:06,490 --> 00:07:09,400 And this happens in the render section. 119 00:07:09,400 --> 00:07:12,160 So as you can see there's this tag here called Pre-render. 120 00:07:12,340 --> 00:07:15,220 And you can see that's where our local scripts were executing. 121 00:07:15,220 --> 00:07:20,280 And then afterwards it's going to do the visualization or rendering and stuff like that. 122 00:07:20,280 --> 00:07:21,690 That's what happens right here. 123 00:07:21,690 --> 00:07:23,760 You can see a tag here called render as well. 124 00:07:23,760 --> 00:07:28,980 So this stuff happens before the frame is rendered. 125 00:07:29,670 --> 00:07:33,450 And then the next one that's going to happen is going to be simulation. 126 00:07:33,450 --> 00:07:36,150 So we can see that this thread was handling simulation. 127 00:07:36,450 --> 00:07:38,160 And let's take a look okay. 128 00:07:38,160 --> 00:07:39,960 Here is our other work. 129 00:07:39,960 --> 00:07:44,830 Unfortunately the tags are a little bit broken here because it's not supposed to be tagged like that. 130 00:07:44,830 --> 00:07:49,090 You can see it says render step work even though this is not render step work. 131 00:07:49,090 --> 00:07:53,830 And if we hover over it you can actually see down in the label it does say pre simulation work. 132 00:07:53,830 --> 00:07:55,780 So I'm not sure why the tag is broken. 133 00:07:55,780 --> 00:08:01,420 I guess that's just a Roblox bug, but as you can see here is our stepped work and here is our pre simulation 134 00:08:01,420 --> 00:08:01,750 work. 135 00:08:01,750 --> 00:08:06,690 So this happens before physics are calculated which occurs right here. 136 00:08:06,690 --> 00:08:08,130 You can see physics stepped. 137 00:08:08,130 --> 00:08:11,790 These were executing right before physics were calculated. 138 00:08:11,790 --> 00:08:16,170 And then we should have the other one that happens before animations which I believe it's this one right 139 00:08:16,170 --> 00:08:16,530 here. 140 00:08:16,530 --> 00:08:19,530 Yes this is pre animation work. 141 00:08:19,530 --> 00:08:23,310 So right here you can see step humanoid step animation. 142 00:08:23,310 --> 00:08:27,540 This is when animations are done or rendered or whatever you want to call it. 143 00:08:27,540 --> 00:08:33,950 But right before we do the animations is when this event is fired, which is our pre animation event. 144 00:08:34,460 --> 00:08:39,560 And then after we do the animation, then it fires the stepped and the pre simulation events. 145 00:08:39,560 --> 00:08:44,240 And then after the physics are done calculating then we hop into heartbeat. 146 00:08:44,240 --> 00:08:46,670 And as you can see here is our heartbeat work. 147 00:08:46,670 --> 00:08:49,280 And here is our post simulation work. 148 00:08:49,280 --> 00:08:56,290 So before we leave the micro profiler, an important thing I want to mention is that all of these run 149 00:08:56,290 --> 00:09:02,950 service events like the Prerender event, the pre animation event, the pre simulation and post simulation 150 00:09:02,950 --> 00:09:09,550 events, all of these have something called a resumption cycle or invocation cycle. 151 00:09:09,550 --> 00:09:16,360 These are points in the frame where any coroutines or scripts that were waiting to be executed are finally 152 00:09:16,360 --> 00:09:20,690 resumed and executed, hence the name resumption cycle. 153 00:09:21,110 --> 00:09:26,090 You can actually see each of these resumption cycles in multiple points in the frame, because they 154 00:09:26,090 --> 00:09:29,270 are tagged with the name deferred threads. 155 00:09:29,270 --> 00:09:30,980 You can see one here for heartbeat. 156 00:09:30,980 --> 00:09:35,330 You can see another one here for stepped or pre simulation. 157 00:09:35,330 --> 00:09:38,090 You can see one here for the pre animation event. 158 00:09:38,090 --> 00:09:41,890 And you can also see one right here for render stepped or pre render. 159 00:09:41,890 --> 00:09:48,910 This means that each of these run service events have their own resumption cycles, for a total of four 160 00:09:48,910 --> 00:09:51,640 resumption cycles in each frame. 161 00:09:51,640 --> 00:09:58,630 There is also an additional resumption cycle specifically for the bind to close method within the data 162 00:09:58,630 --> 00:10:01,720 model, but we won't be focusing on that in this lecture. 163 00:10:01,720 --> 00:10:08,110 Now, to actually see these resumption cycles and action we're going to utilize the task library to 164 00:10:08,110 --> 00:10:14,110 basically push one of these functions or one of these coroutines towards the end of the resumption cycle. 165 00:10:14,110 --> 00:10:18,910 And we can do that by using the task dot defer function and the task library. 166 00:10:18,910 --> 00:10:21,160 So let's do that on heartbeat. 167 00:10:21,160 --> 00:10:27,730 Let me hop back into my local script real quick and inside of the function, listening to my heartbeat 168 00:10:27,730 --> 00:10:28,390 event. 169 00:10:28,390 --> 00:10:35,500 Before I do all of this work I'm going to do is I'm going to call task Dot defer and it says calls slash 170 00:10:35,500 --> 00:10:39,220 resumes a function slash coroutine on the next resumption cycle. 171 00:10:39,220 --> 00:10:44,500 Or basically AKA means it's going to resume it at the end of the current resumption cycle. 172 00:10:45,220 --> 00:10:51,910 So if I do task dot defer function and execute this code in here, you're going to see that this tag 173 00:10:51,910 --> 00:10:57,130 of heartbeat work is going to be pushed towards the end of the heartbeat resumption cycle. 174 00:10:57,130 --> 00:11:03,580 So if we go back and play the game, let me unpause the micro profiler, capture some frames and then 175 00:11:03,580 --> 00:11:05,890 let me pause it again using control and P. 176 00:11:05,890 --> 00:11:11,650 And as you can see, our heartbeat work has moved towards the end of this deferred thread section. 177 00:11:11,650 --> 00:11:16,930 Originally it was the first one, but post simulation is now the first one because we have deferred 178 00:11:16,930 --> 00:11:20,510 heartbeat work towards the end of this resumption cycle. 179 00:11:20,510 --> 00:11:22,700 That's what tasked defer does. 180 00:11:22,700 --> 00:11:28,070 To further demonstrate this, let me get rid of all of these other connections to all the other run 181 00:11:28,070 --> 00:11:34,970 service events, and let's mainly focus on the heartbeat and let's copy this and let's put two more 182 00:11:34,970 --> 00:11:35,480 in here. 183 00:11:35,480 --> 00:11:37,670 But these ones I don't want to defer. 184 00:11:37,670 --> 00:11:40,520 I'm going to have these ones execute immediately. 185 00:11:40,760 --> 00:11:43,730 So we can call this one heartbeat work one. 186 00:11:43,730 --> 00:11:46,340 We'll call this one heartbeat work two and then this one. 187 00:11:46,340 --> 00:11:50,360 Up here we're going to call this heartbeat work last. 188 00:11:50,360 --> 00:11:56,330 So because we're deferring this function to execute at the end of the resumption cycle for the heartbeat 189 00:11:56,330 --> 00:12:02,090 event, this tag in the micro profiler should appear at the very end of the resumption cycle. 190 00:12:02,090 --> 00:12:05,090 So let's capture some frames and then pause. 191 00:12:05,090 --> 00:12:07,130 And then let's go ahead and take a look. 192 00:12:07,130 --> 00:12:08,990 Oh what do you notice. 193 00:12:08,990 --> 00:12:11,810 Here is our deferred thread section. 194 00:12:11,810 --> 00:12:14,630 Here is heartbeat work two heartbeat work one. 195 00:12:14,630 --> 00:12:15,830 Those executed first. 196 00:12:15,830 --> 00:12:21,800 But then as you see the heartbeat work last got pushed to the end of this resumption cycle. 197 00:12:21,800 --> 00:12:25,580 It's the last thing that executes because we used task dot defer. 198 00:12:25,610 --> 00:12:31,240 This task dot defer function works with all of the run service events and their resumption cycles. 199 00:12:31,240 --> 00:12:37,000 So if you're listening to maybe the stepped event or the render stepped event, and you want to push 200 00:12:37,000 --> 00:12:42,640 your function towards the end of the resumption cycle, maybe you need to time something properly. 201 00:12:42,640 --> 00:12:43,720 That's what you can use. 202 00:12:43,720 --> 00:12:50,020 Task dot defer for in case you are having a hard time grasping or understanding resumption cycles. 203 00:12:50,020 --> 00:12:56,520 I also have explained within the course cheat sheet, which is also linked under the resources section 204 00:12:56,520 --> 00:12:57,300 of this lecture. 205 00:12:57,300 --> 00:13:01,140 So if you want to go ahead and check that out after this lecture is over, feel free to do so. 206 00:13:01,140 --> 00:13:01,500 Okay. 207 00:13:01,500 --> 00:13:06,690 So now we're going to get some practice in by using one of the run service events. 208 00:13:06,690 --> 00:13:08,460 I've made this part here. 209 00:13:08,460 --> 00:13:09,600 Feel free to do the same. 210 00:13:09,600 --> 00:13:11,370 And I called it rotate part. 211 00:13:11,370 --> 00:13:13,230 And I make sure to anchor it. 212 00:13:13,230 --> 00:13:15,780 And then I just kind of made it a little bit more elongated. 213 00:13:15,780 --> 00:13:20,290 But what I'm going to do is I'm going to basically have a script that's going to run every single frame, 214 00:13:20,290 --> 00:13:25,810 and we're just going to have this part rotate around and make it look nice and smooth on the screen. 215 00:13:25,810 --> 00:13:29,950 If we look back in the documentation and look at something like the render stepped event, it says the 216 00:13:29,950 --> 00:13:34,360 render step event fires every frame prior to the frame being rendered, which is probably going to be 217 00:13:34,360 --> 00:13:39,370 the event we want to use because we're going to be rotating the part, and we want that to basically 218 00:13:39,370 --> 00:13:42,000 show up before the frame gets rendered. 219 00:13:42,030 --> 00:13:47,340 Now each of these run surface events get passed an argument called Delta time, and according to the 220 00:13:47,340 --> 00:13:53,760 documentation it says delta time is the time in seconds that has elapsed since the previous frame. 221 00:13:53,760 --> 00:13:57,270 So this basically tells you what the time gap is between frames. 222 00:13:57,270 --> 00:14:01,860 So when you render a frame and then you finish rendering the frame, and then you move on to the next 223 00:14:01,860 --> 00:14:07,590 frame, that time it took the previous frame to render and then get to your next frame is what Delta 224 00:14:07,590 --> 00:14:09,420 Time represents. 225 00:14:09,420 --> 00:14:15,630 This number is actually incredibly crucial for allowing you to be able to code logic in your games that 226 00:14:15,630 --> 00:14:19,380 executes properly across multiple different frame rates. 227 00:14:19,380 --> 00:14:25,530 And that's because if somebody is running at 30 frames per second and another person is running at 240 228 00:14:25,530 --> 00:14:29,740 frames per second, this delta time number is going to be different. 229 00:14:29,740 --> 00:14:35,560 In fact, back in studio here with the Micro Profiler open, you can see how long it's taking to render 230 00:14:35,560 --> 00:14:36,550 a single frame. 231 00:14:36,550 --> 00:14:38,980 Right now the average is about seven milliseconds. 232 00:14:38,980 --> 00:14:46,150 So you can basically think of the delta time being around 7.16 milliseconds, because that's how long 233 00:14:46,150 --> 00:14:49,780 it takes to render one frame and then move on to the next frame. 234 00:14:49,780 --> 00:14:56,690 However, that's because I am running at a frame rate of, I believe 240. 235 00:14:56,690 --> 00:14:58,220 Yeah, 240 frames per second. 236 00:14:58,220 --> 00:15:02,210 If I set my frame rate to the default of 60 frames per second. 237 00:15:02,210 --> 00:15:04,250 And then let's reopen the micro profiler. 238 00:15:04,250 --> 00:15:10,100 As you can see, our frame time has completely changed to match that frame rate. 239 00:15:10,100 --> 00:15:16,100 So now instead of averaging around seven milliseconds, we're now hitting about 16 17 milliseconds. 240 00:15:16,100 --> 00:15:18,010 And that would be your new Delta time. 241 00:15:18,010 --> 00:15:22,780 This means if we wanted to do something like a rotate this part every single frame, we needed to be 242 00:15:22,780 --> 00:15:29,170 able to calculate how much we should rotate the part by each frame, depending on what the delta time 243 00:15:29,170 --> 00:15:29,380 is. 244 00:15:29,380 --> 00:15:36,550 Otherwise, if you always rotate the part by the same amount every single frame, no matter what the 245 00:15:36,550 --> 00:15:42,240 delta time is, this part might be rotating faster on some clients, and it might be rotating slower 246 00:15:42,240 --> 00:15:43,410 on other clients. 247 00:15:43,410 --> 00:15:47,070 So what I would like for you to do is I would like for you to create a local script. 248 00:15:47,070 --> 00:15:51,510 You can put in like starter player scripts, and your local script needs to reference your rotating 249 00:15:51,510 --> 00:15:53,700 part, so I'll make a reference to it. 250 00:15:53,700 --> 00:15:57,030 Rotate part is equal to workspace dot rotate part. 251 00:15:57,030 --> 00:16:01,890 And then let me make sure streaming is disabled in the workspace okay good. 252 00:16:01,890 --> 00:16:02,490 It's disabled. 253 00:16:02,490 --> 00:16:04,530 Otherwise I might have to use wait for child here. 254 00:16:05,100 --> 00:16:08,770 And then let's go ahead and grab the run service game. 255 00:16:08,770 --> 00:16:10,210 Get service run service. 256 00:16:10,210 --> 00:16:16,360 And now what I would like for you to do is I would like for you to connect to the render stepped event 257 00:16:16,360 --> 00:16:19,330 and rotate the part every single frame. 258 00:16:19,330 --> 00:16:26,050 And I want you to try using Delta time to make sure that the part rotates at a constant speed, no matter 259 00:16:26,050 --> 00:16:27,160 what the frame rate is. 260 00:16:27,160 --> 00:16:32,520 Now, if you are unsure how to utilize delta Time, then go ahead and attempt this without using Delta 261 00:16:32,520 --> 00:16:34,620 time and I'll show you what to do next. 262 00:16:34,620 --> 00:16:36,510 So pause the lecture right now. 263 00:16:36,510 --> 00:16:39,450 Take a few minutes to work on this and I'll see you in a few. 264 00:16:39,480 --> 00:16:43,980 Okay, so let's try rotating this part using the run service. 265 00:16:43,980 --> 00:16:48,210 So inside of our local script we have a reference to the render step event. 266 00:16:48,210 --> 00:16:51,420 And we're going to connect a function to this event. 267 00:16:51,420 --> 00:16:54,230 And this function is going to be passed Delta time. 268 00:16:54,380 --> 00:16:58,760 But for this first demonstration I'm not going to utilize delta time at all. 269 00:16:58,760 --> 00:17:04,460 So what I need to do is I need to basically just rotate my part around the y axis every single frame. 270 00:17:04,460 --> 00:17:11,660 And a way we could do that is by getting the keyframe of the part and basically adding just a cframe.angles 271 00:17:11,660 --> 00:17:13,370 and rotating it around the y axis. 272 00:17:13,370 --> 00:17:17,450 So we could do times equal, which is plus for keyframes. 273 00:17:17,450 --> 00:17:17,460 frames. 274 00:17:17,460 --> 00:17:19,740 And then we could do c frame dot angles. 275 00:17:19,740 --> 00:17:22,710 And we need to rotate it around the y axis. 276 00:17:22,710 --> 00:17:24,570 How much should we do at each frame. 277 00:17:24,660 --> 00:17:26,280 Because this has to be radians. 278 00:17:26,280 --> 00:17:29,160 Let's say we rotate it by one degree each frame. 279 00:17:29,160 --> 00:17:31,380 So we'll do math dot rad one. 280 00:17:32,220 --> 00:17:35,730 And there is our very basic very simple script. 281 00:17:35,730 --> 00:17:42,590 So if we go and play the game, as you can see our part is rotating by one degree every single frame. 282 00:17:42,590 --> 00:17:50,720 If we open up the micro profiler, this is currently the frame time around 7 to 8 milliseconds. 283 00:17:50,720 --> 00:17:57,440 Now if I open my settings and I switch the maximum frame rate to something lower, like 60 frames per 284 00:17:57,440 --> 00:18:02,630 second, what you're going to notice is now my part is rotating slower, and that's because there's 285 00:18:02,630 --> 00:18:07,420 not as many frames occurring every single second, and because there's not as many frames occurring, 286 00:18:07,420 --> 00:18:13,450 that means this part is only being rotated, I believe 60 degrees per second, while the previous one 287 00:18:13,450 --> 00:18:16,810 was being rotated 240 degrees per second. 288 00:18:16,810 --> 00:18:21,310 So this is a reason why we need to use delta time in our calculations. 289 00:18:21,310 --> 00:18:23,680 So utilizing delta time is very simple. 290 00:18:23,680 --> 00:18:26,470 What we can do is we can basically define a constant. 291 00:18:26,470 --> 00:18:28,330 We can call this rotate speed. 292 00:18:28,420 --> 00:18:33,690 And we can have this number represent how many degrees we want our part to rotate every single second. 293 00:18:33,690 --> 00:18:35,190 So let's say every single second. 294 00:18:35,190 --> 00:18:39,990 We want our part to rotate by 60 degrees no matter the frame rate. 295 00:18:39,990 --> 00:18:42,780 So every single second we're going to rotate by 60 degrees. 296 00:18:42,780 --> 00:18:47,820 So what we need to do is we need to pass that here rotate speed or the 60 degrees. 297 00:18:47,820 --> 00:18:51,990 And now we need to multiply the rotate speed by delta time. 298 00:18:51,990 --> 00:18:56,800 And it's because delta time represents the number that it took from the previous frame. 299 00:18:56,800 --> 00:19:01,090 So rendering the previous frame to reaching this current frame that we're executing in. 300 00:19:01,090 --> 00:19:11,170 So if the delta time is 1/60 of a second, we're going to move or rotate our C frame by 1/60 of this, 301 00:19:11,170 --> 00:19:12,610 which would be one degree. 302 00:19:12,610 --> 00:19:18,550 And then if the delta time changes, maybe the delta time ends up being, I don't know, 1/240 of a 303 00:19:18,550 --> 00:19:19,060 second. 304 00:19:19,060 --> 00:19:24,640 Then we're only going to be rotating the keyframe by 1/240 of 60. 305 00:19:24,640 --> 00:19:31,180 So by incorporating Delta time into our calculation here now the part should always rotate at this exact 306 00:19:31,180 --> 00:19:34,210 same rotate speed, no matter what the frame rate is. 307 00:19:34,210 --> 00:19:35,770 So here we are inside of the game. 308 00:19:35,770 --> 00:19:41,590 Our part is rotating 60 degrees per second, and we're currently running at a frame rate of 60. 309 00:19:41,630 --> 00:19:45,050 Now, let me switch this to a frame rate of 240. 310 00:19:45,710 --> 00:19:46,940 And what do you notice? 311 00:19:46,940 --> 00:19:51,560 Well, I noticed that the part is still rotating at the same speed. 312 00:19:51,560 --> 00:19:57,560 It doesn't matter what I switch my frame rate to if I do 120 still rotating at the same speed. 313 00:19:57,560 --> 00:20:01,820 If I do it at 144, still rotating at the same speed. 314 00:20:01,820 --> 00:20:07,290 So as you can see by using delta time, now our part isn't rotating at different speeds depending on 315 00:20:07,290 --> 00:20:08,070 what the frame rate is. 316 00:20:08,100 --> 00:20:12,120 And this also helps in case maybe your client has like a lag spike. 317 00:20:12,120 --> 00:20:14,340 And the delta time needs to account for that. 318 00:20:14,340 --> 00:20:20,160 By utilizing delta time in your calculations, you are coding correct logic in your games. 319 00:20:20,190 --> 00:20:26,160 Now another important thing I do want to mention is that the render stepped event is not accessible 320 00:20:26,160 --> 00:20:27,660 by server scripts. 321 00:20:27,660 --> 00:20:34,340 So if I were to copy this code and I were to place it inside of a new server script, let me paste it 322 00:20:34,340 --> 00:20:39,560 in there and then let me play the game, you're going to see an error appear. 323 00:20:39,560 --> 00:20:43,190 Render stepped event can only be used from local scripts. 324 00:20:43,190 --> 00:20:49,910 This error only happens with the render step event, which is actually quite interesting because if 325 00:20:49,910 --> 00:20:53,570 you think about the pre render event, that's the same as render steps. 326 00:20:53,570 --> 00:20:57,520 But if we go and run the game, we're not going to have that same error. 327 00:20:57,520 --> 00:20:59,440 And as you can see, our part rotates. 328 00:20:59,440 --> 00:21:07,120 So this leads me to believe that render stepped the stepped event, as well as the heartbeat event, 329 00:21:07,120 --> 00:21:10,390 are all going to be deprecated at some point in the future. 330 00:21:10,390 --> 00:21:15,310 So the alternative events you should be using is going to be run service dot Pre-render. 331 00:21:15,580 --> 00:21:17,380 Pre animation. 332 00:21:17,410 --> 00:21:20,980 pre simulation and post simulation. 333 00:21:20,980 --> 00:21:27,310 Those are going to be the for future new run service events that you should use for any newer projects 334 00:21:27,310 --> 00:21:28,360 you are creating. 335 00:21:28,360 --> 00:21:34,990 Now obviously these new run service events are quite recent because they don't even have any documentation 336 00:21:34,990 --> 00:21:37,480 on the Roblox API website. 337 00:21:37,480 --> 00:21:44,080 So I would keep an eye out for when the old run service events are deprecated and the new ones have 338 00:21:44,080 --> 00:21:46,570 documentation added inside of them. 339 00:21:46,600 --> 00:21:51,280 Alrighty, now let's take a look at some of the methods within the run service. 340 00:21:51,280 --> 00:21:57,190 There are several listed here, but the ones that you'll likely use the most often will be bind to render. 341 00:21:57,190 --> 00:22:03,130 Stepped is client, is server is studio and unbind from render step. 342 00:22:03,130 --> 00:22:08,250 I personally have not used any of the other functions inside of this service, as some of them relate 343 00:22:08,250 --> 00:22:13,530 to, like developing plugins, and I just haven't found a use case for them yet, but that doesn't mean 344 00:22:13,530 --> 00:22:14,730 you will never use them. 345 00:22:14,730 --> 00:22:18,990 Let's take a look at this first one called bind to Render step, which I mentioned earlier, and it 346 00:22:18,990 --> 00:22:24,000 says the bind to render step function binds a custom function to be called at a specific time. 347 00:22:24,000 --> 00:22:25,890 During the render step event. 348 00:22:25,890 --> 00:22:27,630 There are three main arguments for bind. 349 00:22:27,660 --> 00:22:32,730 To render step you got to give a name for your binding, what priority you want it to run at, and what 350 00:22:32,730 --> 00:22:33,780 function needs to be called. 351 00:22:33,780 --> 00:22:39,720 When we encounter the render step phase in a frame, as it is linked to the client's rendering process, 352 00:22:39,720 --> 00:22:44,400 bind to render step can only be called on the client, so you can only do it through local scripts. 353 00:22:44,400 --> 00:22:46,020 So the first parameter is the name. 354 00:22:46,020 --> 00:22:50,610 It's a label for the binding, and it can be used with the unbind from render step function. 355 00:22:50,610 --> 00:22:54,870 If you need to unbind the function and no longer execute it at every single frame. 356 00:22:54,870 --> 00:22:57,510 So that's the purpose of having the name for your binding. 357 00:22:57,510 --> 00:23:02,610 You can use the unbind from render step function to remove the function from the render step event. 358 00:23:02,610 --> 00:23:08,760 The priority of the binding is an integer and determines when during the render step to call the custom 359 00:23:08,760 --> 00:23:12,810 function, the lower this number, the sooner the custom function will be called. 360 00:23:12,810 --> 00:23:18,320 If two bindings have the same priority, the Roblox engine will randomly pick one to run first. 361 00:23:18,320 --> 00:23:25,160 The default Roblox control scripts run with these specific priorities, so player input runs at a priority 362 00:23:25,160 --> 00:23:29,270 of 100 and camera controls runs at a priority of 200. 363 00:23:29,270 --> 00:23:35,720 And for convenience, the render Priority enum can be used to determine the integer value to set a binding. 364 00:23:35,720 --> 00:23:41,480 For example, to make a binding run right before the default camera update, we simply subtract one 365 00:23:41,480 --> 00:23:43,240 from the camera priority level. 366 00:23:43,240 --> 00:23:44,950 So in this example, they give here. 367 00:23:44,950 --> 00:23:51,460 If you want this function to run right before the default or core Roblox scripts updates the camera, 368 00:23:51,460 --> 00:23:57,490 you can access the enum dot render priority dot camera, access the value of that enum and subtract 369 00:23:57,490 --> 00:23:58,180 it by one. 370 00:23:58,180 --> 00:24:01,360 So now this function will execute right before the camera updates. 371 00:24:01,360 --> 00:24:07,250 If you want your function to execute right after the camera updates, maybe you want to override whatever 372 00:24:07,250 --> 00:24:09,170 the core camera scripts do. 373 00:24:09,170 --> 00:24:12,350 Then you can do plus one instead of minus one. 374 00:24:12,350 --> 00:24:17,420 The function you pass to the bind to render step function is also going to be called and given the delta 375 00:24:17,420 --> 00:24:23,090 time, in case you need to use it for making sure the logic of your code works across multiple different 376 00:24:23,090 --> 00:24:23,960 frame rates. 377 00:24:23,960 --> 00:24:26,270 The rest of these methods are pretty straightforward. 378 00:24:26,270 --> 00:24:31,930 For example, is server is a function that simply returns a boolean and it tells you whether or not 379 00:24:31,930 --> 00:24:34,120 you're currently running on the server. 380 00:24:34,120 --> 00:24:39,820 So if you have a server script and you call the is server function, it's going to return true. 381 00:24:39,820 --> 00:24:43,960 If you're in a local script and you call is server, it's going to return false. 382 00:24:43,960 --> 00:24:48,640 If you're in a module script that got required by a server script, it's going to return true. 383 00:24:48,640 --> 00:24:53,680 And likewise, if the module script was required by a local script, this is going to return false. 384 00:24:53,680 --> 00:24:56,380 Same thing with the Is client function. 385 00:24:56,380 --> 00:25:00,790 This one will also return true or false if the current environment is running on the client. 386 00:25:00,790 --> 00:25:06,460 So it's basically just the opposite of is server and then is studio lets you know if you are currently 387 00:25:06,460 --> 00:25:07,870 running in studio. 388 00:25:07,870 --> 00:25:12,580 So whether you're in a local script or a server script, if you're currently play testing or running 389 00:25:12,580 --> 00:25:15,820 the game within studio, this will always return true. 390 00:25:15,820 --> 00:25:20,030 So just as a quick example here inside of my local script, let's just go ahead and print out the run 391 00:25:20,030 --> 00:25:21,800 service is client. 392 00:25:21,800 --> 00:25:28,250 And then let's go to our server script and let's print the other function which is run service is server. 393 00:25:28,250 --> 00:25:32,810 We're going to print this one out and let's see what values both of these return. 394 00:25:32,840 --> 00:25:37,850 They should both print true because this is a server script and this is a local script. 395 00:25:37,850 --> 00:25:42,970 And then on the client side let's also go ahead and utilize the run service bind to render step. 396 00:25:42,970 --> 00:25:45,160 Let's give it a name of a rotate part. 397 00:25:45,160 --> 00:25:48,640 So we're going to move this from the server. 398 00:25:48,640 --> 00:25:51,730 Let me copy this code and just get rid of that on the server. 399 00:25:51,730 --> 00:25:58,360 And we're going to have a priority of let's actually let's take a look at the enum render priority. 400 00:25:58,360 --> 00:25:59,170 What we got in here. 401 00:25:59,170 --> 00:26:01,060 We got character. 402 00:26:01,060 --> 00:26:02,200 This should run after camera. 403 00:26:02,200 --> 00:26:05,770 We got the camera last first input. 404 00:26:05,770 --> 00:26:08,910 Um I'm not sure exactly when we should rotate this part. 405 00:26:08,910 --> 00:26:11,010 I don't think it really matters, does it? 406 00:26:11,010 --> 00:26:12,240 Does it really matter? 407 00:26:12,240 --> 00:26:14,220 Let's do it after the camera updates. 408 00:26:14,220 --> 00:26:14,640 Why not? 409 00:26:14,640 --> 00:26:16,140 So we're going to do camera. 410 00:26:16,290 --> 00:26:19,110 We're going to get the value and we're just going to do plus one. 411 00:26:19,110 --> 00:26:21,840 And then we need to pass our function to make it really easy. 412 00:26:21,840 --> 00:26:23,730 I'm just going to put a lambda function here. 413 00:26:23,730 --> 00:26:26,160 Let's paste that rotating code. 414 00:26:26,310 --> 00:26:29,340 Uh we're going to need to access delta time here. 415 00:26:30,370 --> 00:26:31,510 Delta time. 416 00:26:31,510 --> 00:26:35,500 And then we also need to define our rotate speed. 417 00:26:35,500 --> 00:26:36,730 Let's make it a little bit faster. 418 00:26:36,730 --> 00:26:39,310 Let's do like 240 degrees per second okay. 419 00:26:39,310 --> 00:26:40,120 There we go. 420 00:26:40,360 --> 00:26:43,990 And we also need a variable reference to our rotate part. 421 00:26:43,990 --> 00:26:45,760 So workspace dot rotate part okay. 422 00:26:45,760 --> 00:26:46,270 Perfect. 423 00:26:46,270 --> 00:26:53,320 So now we have basically converted our code to use the bind to render step function, which also means 424 00:26:53,320 --> 00:26:58,760 at some point in the future, if we no longer want to have this function executing at render step, 425 00:26:58,760 --> 00:27:04,190 let's say five seconds in the future, for some reason, we want to no longer execute this code right 426 00:27:04,190 --> 00:27:04,460 here. 427 00:27:04,460 --> 00:27:10,730 We can simply use the unbind from render step and give it the name which was our rotate part. 428 00:27:10,730 --> 00:27:13,400 So let's go ahead and hop in, play test the game. 429 00:27:13,400 --> 00:27:16,160 And as you can see both of those scripts printed true. 430 00:27:16,160 --> 00:27:17,300 Server printed true. 431 00:27:17,330 --> 00:27:22,630 The client printed true for the Is client method, and then it printed true on the server for the Is 432 00:27:22,630 --> 00:27:24,280 server method, which makes sense. 433 00:27:24,280 --> 00:27:30,850 My part is no longer rotating because I believe that function got unblinded from or unbound from render 434 00:27:30,850 --> 00:27:31,270 step. 435 00:27:31,270 --> 00:27:34,240 So actually let's make that delay a little bit longer. 436 00:27:34,870 --> 00:27:37,000 Let's make the delay like 10s. 437 00:27:37,000 --> 00:27:39,910 And let's hop back into the game and let's see if our parts rotate. 438 00:27:39,940 --> 00:27:40,390 All right. 439 00:27:40,390 --> 00:27:41,920 Our parts rotating rotating. 440 00:27:41,920 --> 00:27:44,850 And eventually it should stop here at any second. 441 00:27:45,930 --> 00:27:46,500 There we go. 442 00:27:46,500 --> 00:27:53,520 Now our part is no longer rotating because the function has no longer been binded to the run service 443 00:27:53,520 --> 00:27:55,050 render stepped event. 444 00:27:55,080 --> 00:28:00,990 Now, I'm actually curious to see if Roblox will provide another function in the future, since I believe 445 00:28:00,990 --> 00:28:03,090 render stepped is going to be deprecated. 446 00:28:03,090 --> 00:28:09,380 Maybe they'll have like a function called run service bind to Prerender. 447 00:28:09,380 --> 00:28:13,520 Maybe they'll have a function like that in the future that literally does the exact same thing. 448 00:28:13,520 --> 00:28:14,060 Who knows. 449 00:28:14,060 --> 00:28:15,260 We'll see what happens. 450 00:28:15,260 --> 00:28:15,980 Alrighty. 451 00:28:15,980 --> 00:28:18,920 And that's basically the gist of the run service. 452 00:28:18,920 --> 00:28:24,710 It's a simple service that allows you to schedule and execute code on a frame by frame basis. 453 00:28:24,710 --> 00:28:31,380 And they give us, you know, several events to be able to execute code at certain points in the frame, 454 00:28:31,380 --> 00:28:36,840 like if you want to run code before the screen is rendered, you can use pre render if you want to do 455 00:28:36,840 --> 00:28:39,510 it before animations are calculated or whatever. 456 00:28:39,510 --> 00:28:44,700 Use pre animation if you want to do it before the physics calculations, use pre simulation or if you 457 00:28:44,700 --> 00:28:48,870 want to schedule code at the very end of the frame, then you can use post simulation. 458 00:28:48,870 --> 00:28:51,840 That's going to be everything from me for this lecture. 459 00:28:51,840 --> 00:28:54,600 Thank you for watching and I'll see you next time.